/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2021-08-20 14:05:47
 * @LastEditors: ding
 * @LastEditTime: 2022-09-26 18:27:02
 * @Description: 海清机器，时间、重启、等设备设置接口的封装tools工具
 */
import { actions, actions as haiqingActions } from "../../http/actions";
import { DateFormat } from "@diyaner/ding";
import { hc } from "../../hc";
import HcWanBaseCmdService from "./HcWanBaseCmdService";

/** 海清机器时间处理等零散工具接口 */
export default class MachineToolsWanService extends HcWanBaseCmdService {
	/** 获取设备系统时间 */
	async getSysTime() {
		const operator = haiqingActions.GetSysTime;
		const deviceId = this.device.deviceId;
		const res = await this.execCMD<{ info: hc.http.dateTime }>(operator, {});
		if (res) {
			if (!res.success) throw new Error("获取设备时间失败" + deviceId);
			const deviceTime: hc.http.dateTime = (
				res.data[0] as unknown as { info: hc.http.dateTime }
			).info;
			const formatTime1 = `${deviceTime.Year}-${deviceTime.Month}-${deviceTime.Day} ${deviceTime.Hour}:${deviceTime.Minute}:${deviceTime.Second}`;
			const formatTime = DateFormat.init(formatTime1).format();
			deviceTime.dateTime = formatTime;
			return deviceTime;
		} else {
			this.app.logger.error("获取设备时间失败! %s", deviceId);
			throw new Error("获取机器时间失败！" + deviceId);
		}
	}

	/**
	 *
	 * 设置设备系统时间
	 *
	 * @param {hc.http.dateTime} [outDate] 外部时间 可选，如果未设置，时间会等到下一次轮询才确定服务器当前时间
	 * @return {*}
	 * @memberof MachineToolsWanService
	 */
	async setSysTime(outDate?: hc.http.dateTime) {
		const operator = haiqingActions.SetSysTime;
		let data;
		if (outDate) {
			data = {
				info: outDate,
			};
		} else {
			const df = new Date();
			data = {
				info: {
					Year: df.getFullYear(),
					Month: df.getMonth() + 1,
					Day: df.getDate(),
					Hour: df.getHours(),
					Minute: df.getMinutes(),
					Second: df.getSeconds(),
				},
				// 例外标记，下发命令时再使用后剔除
				isOutDate: outDate ? true : false,
			};
		}
		const deviceId = this.device.deviceId;

		const res = await this.execCMD(operator, data);
		if (!res) {
			this.app.logger.warn(
				"未能从redis中读取到命令结果 设备 %s 命令 %s  ",
				deviceId,
				operator
			);
			throw new Error("设置设备时间出错 未能从redis中读取到命令结果");
		}
		if (res.success) {
			return res;
		} else {
			throw new Error("设置设备时间出错 " + JSON.stringify(res.data));
		}
	}

	/**
	 *
	 * 设置用户名，密码
	 *
	 * 注意设置新用户名密码之后 应使用新的机器配置请求机器
	 *
	 * @param {string} userName
	 * @param {string} password
	 * @return {*}
	 * @memberof MachineToolsWanService
	 */
	async setUserNameAndPassword(userName: string, password: string) {
		const operator = actions.SetUserPwd;

		const data = {
			info: {
				User: userName,
				Pwd: password,
			},
		};

		const res = await this.execCMD(operator, data);
		if (!res) {
			this.app.logger.warn(
				"未能从redis中读取到命令结果 设备 %s 命令 %s  ",
				this.device.deviceId,
				operator
			);
			throw new Error("设置用户名密码出错 未能从redis中读取到命令结果");
		}
		if (res.success) {
			return res;
		} else {
			throw new Error("设置用户名密码出错 " + JSON.stringify(res.data));
		}
	}

	/**
	 *
	 * 重启设备
	 *
	 * @return {*}
	 * @memberof MachineToolsWanService
	 */
	async rebootDevice() {
		const operator = actions.RebootDevice;
		const data = {
			info: {
				IsRebootDevice: 1,
				DeviceID: this.device.deviceId,
			},
		};
		this.app
			.getLogger("haiqing")
			.warn(
				"[海清机器，特殊操作日志，后台重启设备] 操作用户 %s 设备id %s",
				this.app.currentContext?.getUserId() || "unknown",
				this.device.deviceId
			);

		await this.saveCacheCMD(operator, data);
		return {
			success: null,
			msg: "已准备好命令，请稍候查看设备是否重启！",
		};
	}

	/**
	 *
	 * 远程开门指令
	 *
	 * @param {string} [msg="远程开门"]
	 * @return {*}
	 * @memberof MachineToolsWanService
	 */
	async openDoor(msg = "远程开门") {
		const operator = actions.OpenDoor;
		const data = {
			info: {
				DeviceID: this.device.deviceId,
				status: 1,
				msg,
			},
		};
		this.app
			.getLogger("haiqing")
			.warn(
				"[海清机器，特殊操作日志，后台远程开门] 操作用户 %s 设备id %s",
				this.app.currentContext?.getUserId() || "unknown",
				this.device.deviceId
			);

		const res = await this.execCMD(operator, data);
		if (!res) {
			this.app.logger.warn(
				"未能从redis中读取到命令结果 设备 %s 命令 %s ",
				this.device.deviceId,
				operator
			);
			throw new Error("远程开门出错 未能从redis中读取到命令结果");
		}
		if (res.success) {
			return res;
		} else {
			throw new Error("远程开门出错 " + JSON.stringify(res.data));
		}
	}
}
